﻿package fpc.containers;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import fpc.containers.ScrollBarMode;
import fpc.layouts.ILayout;
import fpc.controls.mutators.ScrollBar;

class ScrollBox< T:ILayout > extends Container<T>
{
	var _vScrollBar:ScrollBar;
	
	var _hScrollBar:ScrollBar;
	
	var _scrollRect:Rectangle;
	
	public function new() 
	{
		_vScrollBarMode = AUTO;
		_hScrollBarMode = AUTO;
		_scrollRect = new Rectangle();
		super();
		createHScrollBar();
		createVScrollBar();
		mouseWheel = true;
	}
	
	function createHScrollBar()
	{
		_hScrollBar = new ScrollBar(true);
		_hScrollBar.parent = this;
		_hScrollBar.addTo(_sprite);
		_hScrollBar.heraldChange.add(onHScroll);
	}
	
	function createVScrollBar()
	{
		_vScrollBar = new ScrollBar(false);
		_vScrollBar.parent = this;
		_vScrollBar.addTo(_sprite);
		_vScrollBar.heraldChange.add(onVScroll);
	}
	
	function onHScroll(scrollBar:ScrollBar)
	{
		_scrollRect.x = Std.int(_hScrollBar.value);
		_containerSprite.scrollRect = _scrollRect;
	}
	
	function onVScroll(scrollBar:ScrollBar)
	{
		_scrollRect.y = Std.int(_vScrollBar.value);
		_containerSprite.scrollRect = _scrollRect;
	}
	
	function onMouseWheel(event:MouseEvent)
	{
		_vScrollBar.value -= event.delta * _vScrollBar.clickStep;
	}
	
	function arranteScrollBars()
	{
		var isVScrollBar = _vScrollBar != null && _vScrollBar.visible;
		var isHScrollBar = _hScrollBar != null && _hScrollBar.visible;
		var areaHeight = _height;
		if (isHScrollBar)
		{
			areaHeight = _height - _hScrollBar.height;
			_hScrollBar.y = areaHeight;
			_hScrollBar.width = isVScrollBar ? _width - _vScrollBar.width : _width;
		}
		var areaWidth = _width;
		if (isVScrollBar)
		{
			areaWidth = _width - _vScrollBar.width;
			_vScrollBar.x = areaWidth;
			_vScrollBar.height = _height;
		}
		if (isHScrollBar)
		{
			_hScrollBar.pageScrollSize = areaWidth;
			_hScrollBar.fullScrollSize = _scrollWidth;
		}
		if (isVScrollBar)
		{
			_vScrollBar.pageScrollSize = areaHeight;
			_vScrollBar.fullScrollSize = _scrollHeight;
		}
		if (_scrollRect.x > _hScrollBar.value)
		{
			_scrollRect.x = _hScrollBar.value;
		}
		if (_scrollRect.y > _vScrollBar.value)
		{
			_scrollRect.y = _vScrollBar.value;
		}
		_scrollRect.width = areaWidth;
		_scrollRect.height = areaHeight;
		_containerSprite.scrollRect = _scrollRect;
	}
	
	override function render()
	{
		arranteScrollBars();
	}
	
	var _scrollWidth:Float;
	
	var _scrollHeight:Float;
	
	override function arrange()
	{
		var newWidth = _width;
		var newHeight = _height;
		var scrollWidth = _width;
		var scrollHeight = _height;
		if (_vScrollBar != null)
		{
			scrollWidth -= _vScrollBar.width;
			_width = scrollWidth;
		}
		if (_hScrollBar != null)
		{
			scrollHeight -= _hScrollBar.height;
		}
		
		super.arrange();
		
		if (_width <= scrollWidth + .1 && _hScrollBarMode == AUTO)
		{
			_hScrollBar.visible = false;
			scrollHeight = newHeight;
		}
		else
		{
			_hScrollBar.visible = true;
		}
		
		if (_height <= scrollHeight && _vScrollBarMode == AUTO)
		{
			_vScrollBar.visible = false;
			_width = newWidth;
			_height = newHeight - .1;
			
			_isArrangeValid = false;
			super.arrange();
			
			if (_width <= newWidth + .1 && _hScrollBarMode == AUTO)
			{
				_hScrollBar.visible = false;
			}
		}
		else
		{
			_vScrollBar.visible = true;
		}
		
		_scrollWidth = _width;
		_scrollHeight = _height;
		_width = newWidth;
		_height = newHeight;
		
		// TODO Распределить по-нормальному обязанности между arrange и render
		orderRender();
	}
	
	public var vScrollBarMode(getVScrollBarMode, setVScrollBarMode):ScrollBarMode;
	var _vScrollBarMode:ScrollBarMode;
	function getVScrollBarMode()
	{
		return _vScrollBarMode;
	}
	function setVScrollBarMode(value)
	{
		_vScrollBarMode = value;
		orderArrange();
		return _vScrollBarMode;
	}
	
	public var hScrollBarMode(getHScrollBarMode, setHScrollBarMode):ScrollBarMode;
	var _hScrollBarMode:ScrollBarMode;
	function getHScrollBarMode()
	{
		return _hScrollBarMode;
	}
	function setHScrollBarMode(value)
	{
		_hScrollBarMode = value;
		orderArrange();
		return _hScrollBarMode;
	}
	
	public var mouseWheel(getMouseWheel, setMouseWheel):Bool;
	var _mouseWheel:Bool;
	function getMouseWheel()
	{
		return _mouseWheel;
	}
	function setMouseWheel(value)
	{
		if (value != _mouseWheel)
		{
			_mouseWheel = value;
			if (value)
			{
				_containerSprite.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
			}
			else
			{
				_containerSprite.removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
			}
		}
		return _mouseWheel;
	}
}